package com.sleepcamel.rest.domain;

import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@SuppressWarnings("unchecked")
public class TreeNode extends NamedBaseBean {

	protected transient Object parent;
	protected List<TreeNode> childs = new ArrayList<TreeNode>();

	public <P> P getParent() {
		return (P) parent;
	}

	public <P> void setParent(P parent) {
		this.parent = parent;
	}
	
	public void fixParentHood() {
		for(TreeNode child:childs){
			child.setParent(this);
			child.fixParentHood();
		}
	}
	
	public <C extends TreeNode> void addChild(C child) {
		addChild(child, true);
	}
	
	protected <C extends TreeNode> void addChild(C child, boolean fireEvent) {
		childs.add(child);
		child.setParent(this);
		if ( fireEvent ){
			support.firePropertyChange("child", null, child);
		}
	}
	
	public <C extends TreeNode> void addChilds(Collection<C> newChilds) {
		for(C child:newChilds){
			addChild(child, false);
		}
		support.firePropertyChange("childs", null, this.childs);
	}
	
	public <C> void removeChild(C child) {
		removeChild(child, true);
	}

	protected <C> void removeChild(C child, boolean fireEvent) {
		childs.remove(child);
//		child.removePropertyChangeListeners();
		if ( fireEvent ){
			support.firePropertyChange("childs", null, this.childs);
		}
	}
	
	public <C> void removeChilds(Collection<C> newChilds) {
		for(C child:newChilds){
			removeChild(child, false);
		}
		support.firePropertyChange("childs", null, this.childs);
	}
	
	public <C extends TreeNode> List<C> getChilds() {
		return (List<C>) childs;
	}

	
	public <C extends TreeNode> void setChilds(List<C> childs) {
		this.childs = (List<TreeNode>) childs;
	}

	public void addPropertyChangeListener(PropertyChangeListener listener) {
		super.addPropertyChangeListener(listener);
		for(TreeNode child:childs){
			child.addPropertyChangeListener(listener);
		}
	}
	
	@Override
	public void removePropertyChangeListener(PropertyChangeListener listener) {
		super.removePropertyChangeListener(listener);
		for(TreeNode child:childs){
			child.removePropertyChangeListener(listener);
		}
	}
	
	public void removePropertyChangeListeners() {
		super.removePropertyChangeListeners();
		for(TreeNode child:childs){
			child.removePropertyChangeListeners();
		}
	}
}
